package com.framework.common.mongodb.builder;

import com.framework.common.mongodb.entity.QueryEntity;
import com.framework.common.mongodb.em.QueryModel;
import org.springframework.data.mongodb.core.query.Criteria;

import java.util.Map;

/**
 * \* Created with IntelliJ IDEA.
 * \* User: ywb
 * \* Date: 2021/11/19
 * \* Time: 13:57
 * \* Description:
 * \
 */
public class QueryBuilder {
    private Map<String, QueryEntity> map;
    private QueryModel model;
    private Criteria qc;
    private Criteria[] qdata;

    public QueryBuilder(final Map<String, QueryEntity> map, final QueryModel model) {
        this.map = null;
        this.qc = new Criteria();
        this.map = map;
        this.model = model;
        this.qdata = new Criteria[map.size()];
    }

    public Criteria queryCriteria() {
        int i = 0;
        for (final Map.Entry<String, QueryEntity> entry : this.map.entrySet()) {
            final QueryEntity entity = entry.getValue();
            final Criteria criteriaand = new Criteria();
            final Criteria c = new Criteria();
            this.insert(c, entity);
            criteriaand.andOperator(new Criteria[] { c });
            this.qdata[i] = c;
            ++i;
        }
        if (i == 0) {
            return this.qc;
        }
        switch (this.model) {
            case AND: {
                this.qc.andOperator(this.qdata);
                break;
            }
            case OR: {
                this.qc.orOperator(this.qdata);
                break;
            }
            case NOR: {
                this.qc.norOperator(this.qdata);
                break;
            }
            case IN: {
                this.qc.in((Object[])this.qdata);
                break;
            }
            case NIN: {
                this.qc.nin((Object[])this.qdata);
                break;
            }
        }
        return this.qc;
    }

    public void insert(final Criteria c, final QueryEntity entity) {
        final Criteria tc = c.and(entity.getField());
        for (int i = 0; i < entity.getType().length; ++i) {
            switch (entity.getType()[i]) {
                case GT: {
                    tc.gt(entity.getValue()[i]);
                    break;
                }
                case LT: {
                    tc.lt(entity.getValue()[i]);
                    break;
                }
                case GTE: {
                    tc.gte(entity.getValue()[i]);
                    break;
                }
                case LTE: {
                    tc.lte(entity.getValue()[i]);
                    break;
                }
                case IS: {
                    tc.is(entity.getValue()[i]);
                    break;
                }
                case REGEX: {
                    if (entity.getValue()[i] != null) {
                        tc.regex(entity.getValue()[i].toString());
                        break;
                    }
                    break;
                }
                case IN: {
                    tc.in(entity.getValue());
                    break;
                }
                case NIN: {
                    tc.nin(entity.getValue());
                    break;
                }
                case NE: {
                    if (entity.getValue() != null) {
                        tc.ne(entity.getValue()[i]);
                        break;
                    }
                    break;
                }
            }
        }
    }


}
